<template>
  <div class="app-container">
    <div class="left_container">
      <div class="mobile">
        <img src="../../../assets/image/wx.png" alt="" />
        <span class="mobile_title">{{ stationName }}</span>
        <div class="subMenu" v-show="menuOpen">
          <div style="width: 45px"></div>
          <div class="subBtn">
            <div
              class="sub_btn"
              v-for="(v, index) in menuList.length"
              :class="{ hidden: subIndex != v - 1 }"
            >
              <div v-if="sub_buttonList.length < 5" @click="addSubBtn(index)">
                <el-button class="add_btn" :class="{ newBtn: editSubIndex }"
                  >+</el-button
                >
              </div>
              <div
                class="sub_content"
                v-for="(subItem, index) in sub_buttonList"
                :key="index"
                @click="handleSub(subItem, index)"
              >
                <el-button
                  class="add_btn"
                  :class="{ newBtn2: index === editSubIndex }"
                  >{{ subItem.name }}</el-button
                >
              </div>
            </div>
            <!-- 用来填充样式的 无功能 -->
            <div class="sub_btn hidden" v-if="menuList.length < 3">
              <div v-if="sub_buttonList.length < 5">
                <el-button class="add_btn">+</el-button>
              </div>
            </div>
          </div>
          <!-- <div v-for="subitem in sub_buttonList" :key="subitem.name" >{{ subitem.name }}</div> -->
        </div>
        <div class="btn">
          <div class="icon_btn">
            <img src="../../../assets/image/keyboard.png" alt="" />
          </div>
          <div
            class="main_btn"
            v-for="(ele, index) in menuList"
            :key="index"
            @click="handleMenu(ele, index)"
          >
            <el-button
              plain
              class="main_btn1"
              :class="{ newBtn2: index === mainIndex }"
              >{{ ele.name }}</el-button
            >
          </div>
          <div class="main_btn" v-if="menuList.length < 3">
            <el-button plain class="main_btn1" @click="addBtn()">+</el-button>
          </div>
        </div>
      </div>
    </div>
    <div class="right_container" v-show="isShow">
      <div class="alt">请点击左侧菜单栏，进行编辑操作</div>
    </div>
    <div class="right_container" v-if="!isShow">
      <div class="setting">
        <div class="title">{{ title }}</div>
        <div class="content">
          <el-form ref="settingForm" :model="settingForm" :rules="rules">
            <el-form-item label="名称" prop="name">
              <el-input
                style="width: 40%; margin: 0 20px"
                :placeholder="`请输入${title.slice(0, -2)}名称`"
                v-model="settingForm.name"
                size="mini"
              />
              <el-button type="text" @click="handleDel()">删除菜单</el-button>
            </el-form-item>
            <div
              v-if="inputTip == 0"
              style="font-size: 12px; color: #8c939d; margin-left: 4rem"
            >
              仅支持中英文和数字,字数不超过4个汉字或8个字母
            </div>
            <div
              v-if="inputTip == 1"
              style="font-size: 12px; color: #8c939d; margin-left: 4rem"
            >
              仅支持中英文和数字，字数不超过8个汉字或16个字母
            </div>
            <el-form-item label="菜单类型" style="margin-top: 2rem">
              <el-radio-group v-model="settingForm.type">
                <el-radio v-if="settingForm.type == 'media_id'" label="media_id"
                  >发送消息</el-radio
                >
                <el-radio v-else label="click">发送消息</el-radio>
                <el-radio label="view">跳转网页</el-radio>
                <el-radio label="miniprogram">跳转小程序</el-radio>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="内容" prop="url">
              <div class="form_content">
                <div
                  v-if="
                    settingForm.type == 'click' ||
                    settingForm.type == 'media_id'
                  "
                >
                  <el-radio-group
                    v-model="settingForm.type"
                    style="margin: 2rem"
                  >
                    <el-radio-button label="click">文本</el-radio-button>
                    <el-radio-button label="media_id">图片</el-radio-button>
                  </el-radio-group>
                  <div v-if="settingForm.type == 'click'">
                    <el-input
                      type="textarea"
                      placeholder="请输入消息内容"
                      v-model="settingForm.key"
                      maxlength="64"
                      show-word-limit
                      proper-class="data-class"
                      :append-to-body="false"
                    />
                  </div>
                  <div v-if="settingForm.type == 'media_id'">
                    <el-upload
                      class="avatar-uploader"
                      :action="addressUrl"
                      :headers="headers"
                      :show-file-list="false"
                      accept="image/png,image/jpg"
                      :before-upload="beforeAvatarUpload"
                      :on-success="handleAvatarSuccess"
                    >
                      <img
                        v-if="settingForm.headImg"
                        :src="settingForm.headImg"
                        class="avatar"
                      />
                      <img
                        v-else-if="settingForm.value"
                        :src="settingForm.value"
                        class="avatar"
                      />

                      <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                      <div class="el-upload__tip" slot="tip">大小不超过2M</div>
                    </el-upload>
                  </div>
                </div>
                <div class="pageUrl" v-if="settingForm.type == 'view'">
                  网页链接
                  <el-input
                    placeholder="请输入页面地址"
                    v-model="settingForm.url"
                    style="width: 60%; margin-left: 10px"
                  />
                </div>
                <div
                  v-if="settingForm.type == 'view'"
                  style="color: #1e1e29c7; padding-left: 5rem; font-size: 12px"
                >
                  请以http://或https://开头，订阅者点击会跳到此链接
                </div>
                <div v-if="settingForm.type == 'miniprogram'">
                  <div class="xcx">
                    关联小程序
                    <img src="settingForm.url" alt="" />
                    <span>{{ stationName }}</span>
                  </div>
                  <div class="pageUrl">
                    小程序路径
                    <el-input
                      placeholder="请输入页面地址"
                      v-model="settingForm.pagepath"
                      style="width: 60%; margin-left: 10px"
                    />
                  </div>
                  <div
                    style="
                      color: #1e1e29c7;
                      padding-left: 5.5rem;
                      font-size: 12px;
                    "
                  >
                    用户点击此菜单会跳转到当前路径的小程序
                  </div>
                </div>
              </div>
            </el-form-item>
          </el-form>
        </div>
      </div>
      <div class="footer">
        <el-button type="primary" @click="submit" :loading="loading"
          >保存并发布</el-button
        >
      </div>
    </div>
  </div>
</template>
<script>
import {
  getMenuBar,
  getAppId,
  addMenu,
  uploadWxImgDto,
} from "@/api/MenuSetting/index";
import { getToken } from "@/utils/auth";
import { cloneDeep } from "lodash";

export default {
  name: "MenuSetting",
  data() {
    var validateURL = (rule, value, callback) => {
      if (!value) {
        callback();
      } else {
        const pattern = /^(http|https):\/\//; // 正则表达式匹配模式
        if (!pattern.test(value)) {
          callback(new Error("网页链接不正确"));
        }
      }
      callback();
    };
    // var validateTitle = (rule, value, callback) => {
    //   if (value && this.settingForm.type == 'click') {
    //     const chineseCharCount = (value.match(/[\u4e00-\u9fa5]/g) || []).length; // 统计汉字个数
    //     const otherCharCount = value.length - chineseCharCount; // 统计非汉字个数
    //     if (chineseCharCount * 2 + otherCharCount > rule.max) {
    //       callback(new Error(`最多${rule.max}个字符`));
    //     } else {
    //       callback();
    //     }
    //   } else {
    //     callback();
    //   }
    // };
    // 后端数据全量更新， 需要自己组装参数
    return {
      loading: false,
      edit: false, // 编辑判断
      mainIndex: "", // 控制主菜单的高亮
      editSubIndex: "", //编辑二级菜单索引
      title: "菜单设置",
      menuOpen: false, // 是否展示 二级菜单
      subIndex: "", //索引用来 展示不同 二级菜单
      menuList: [], //主菜单
      currentList: [], //主菜单原件
      activeMenu: {}, //选中的一级菜单
      inputTip: 0, //输入框 校验提示切换
      sub_buttonList: [], //子菜单
      stationName: this.$store.state.user.nickName,
      rules: {
        // name: [{ validator: validateName, trigger: "change" }],
        url: [
          { validator: validateURL, trigger: "blur" },
          // { validator: validateTitle, trigger: "blur", max: 64 },
        ],
      },
      settingForm: {},
      pageUrl: "",
      appid: "", //小程序需要配置 appid
      addressUrl: process.env.VUE_APP_BASE_API + "/common/upload",
      headers: {
        Authorization: "Bearer " + getToken(),
      },
      isSub: false, // 选中的是几级菜单 true 为二级
    };
  },
  created() {
    this.getMenuBarList();
    this.getApp();
  },
  computed: {
    // 右侧菜单设置控制
    isShow() {
      // 是否选中主菜单
      return Object.keys(this.activeMenu).every(
        (key) => !this.activeMenu.hasOwnProperty(key)
      );
    },
  },
  watch: {
    menuOpen: {
      handler(newVal) {
        if (newVal) {
          this.sub_buttonList = [];
          if (
            this.currentList[this.subIndex] &&
            this.currentList[this.subIndex].sub_button &&
            this.currentList[this.subIndex].sub_button.list
          ) {
            this.sub_buttonList = cloneDeep(
              this.currentList[this.subIndex].sub_button.list
            );
          }
        }
      },
    },
    // 动态展示 二级菜单
    activeMenu: {
      handler(newVal, oldVal) {
        this.sub_buttonList = [];
        if (newVal.sub_button && newVal.sub_button.list) {
          this.sub_buttonList = cloneDeep(newVal.sub_button.list);
        }
      },
      deep: true,
      immediate: true,
    },
    "settingForm.type": {
      handler(newVal) {
        if (newVal == "click") {
          delete this.settingForm.headImg;
        }
        if (newVal == "media_id") {
          delete this.settingForm.key;
        }
      },
    },
    // 输入框校验
    "settingForm.name": {
      handler(newVal) {
        if (this.inputTip == 0) {
          newVal = this.truncateText(newVal, 4, 8, 8);
        } else if (this.inputTip == 1) {
          newVal = this.truncateText(newVal, 8, 16, 16);
        }
        // 手动更新 settingForm.name 的值
        this.$set(this.settingForm, "name", newVal);
        //  if(!newVal && this.inputTip == 0 ) {
        //       this.$set(this.settingForm, 'name', '菜单名称');
        //     }
      },
    },
  },
  methods: {
    // 保存
    async submit() {
      await this.$confirm(`是否确认发布`, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      });
      this.loading = true;
      let button = cloneDeep(this.currentList);
      let data = cloneDeep(this.settingForm);
      // 组装 菜单
      if (this.isSub) {
        if (!button[this.subIndex].sub_button) {
          button[this.subIndex].sub_button = { list: [] };
        }
        // 子菜单新增还是编辑判断
        if (this.edit) {
          button[this.subIndex].sub_button.list.unshift(data);
        } else {
          button[this.subIndex].sub_button.list.splice(
            this.editSubIndex,
            1,
            data
          );
        }
      } else {
        button[this.subIndex] = data;
      }
      // 如果数组中存在图片 需要 拿到 media_id的值
      button = await this.processArray(button);
      console.log(JSON.stringify({ button: button }));
      try {
        await addMenu(JSON.stringify({ button: button }));
        this.$message.success("菜单配置发布中，请稍后验证~");
      } catch (err) {
        this.settingForm = {};
        this.menuOpen = !this.menuOpen;
      } finally {
        await this.getMenuBarList();
        this.loading = false;
        this.edit = false;
      }
    },
    // 获取appId
    async getApp() {
      const res = await getAppId(
        this.$store.state.user.presentEnterprise.enterpriseId
      );
      this.appid = res.data.appId;
    },
    // 点击二级菜单
    handleSub(ele, index, type = false) {
      this.edit = type;
      this.editSubIndex = index;
      this.mainIndex = "";
      this.isSub = true;
      this.settingForm = {};
      this.title = "子菜单设置";
      this.inputTip = 1;
      this.settingForm = ele;
      if (!this.settingForm.type) {
        this.$set(this.settingForm, "type", "click");
      }
    },
    // x新增子菜单
    addSubBtn(index) {
      this.sub_buttonList.unshift({ name: "子菜单名称" });
      this.handleSub(this.sub_buttonList[0], 0, true);
    },
    // 新增主菜单
    addBtn() {
      this.menuList.push({ name: "菜单名称" });
      this.handleMenu(
        this.menuList[this.menuList.length - 1],
        this.menuList.length - 1
      );
      // this.activeMenu = this.menuList[this.menuList.length -1];
    },
    // 选中主菜单
    handleMenu(ele, index) {
      this.settingForm = {};
      this.title = "菜单设置";
      this.subIndex = index;
      this.mainIndex = index;
      this.isSub = false;
      this.menuOpen = !this.menuOpen;
      this.activeMenu = ele;
      this.inputTip = 0;
      this.settingForm = ele;
      this.editSubIndex = "";
      if (!this.settingForm.type) {
        this.$set(this.settingForm, "type", "click");
      }
    },
    // 获取公众号菜单
    async getMenuBarList() {
      const res = await getMenuBar();
      if (res.data.selfmenu_info) {
        this.menuList = res.data.selfmenu_info.button; // 编辑用的
        this.currentList = cloneDeep(res.data.selfmenu_info.button); // 原件
      }
    },

    // 删除菜单
    async handleDel() {
      await this.$confirm(
        `确认删除此菜单“${this.settingForm.name}”吗？`,
        "警告",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }
      );
      let button = cloneDeep(this.currentList);
      let data = cloneDeep(this.settingForm);
      // 组装 菜单
      if (this.isSub) {
        let subBtn = button[this.subIndex].sub_button;
        if (subBtn) {
          subBtn.list = subBtn.list.filter((ele) => {
            return ele.name != data.name;
          });
          if (subBtn.list.length == 0) {
            delete button[this.subIndex].sub_button;
          }
        }
      } else {
        button.splice(this.subIndex, 1);
      }
      // 如果数组中存在图片 需要 拿到 media_id的值
      button = await this.processArray(button);
      console.log(JSON.stringify({ button: button }));
      await addMenu(JSON.stringify({ button: button }));
      await this.getMenuBarList();
      this.settingForm = {};
      this.menuOpen = !this.menuOpen;
      this.$message.success("删除成功");
    },
    // 上传图片
    beforeAvatarUpload(file) {
      const isLt2M = file.size / 1024 / 1024 < 2;
      const isJPG = file.type == "image/jpg";
      const isPNG = file.type == "image/png";
      const isJPEG = file.type == "image/jpeg";
      console.log(file.type);
      if (!isLt2M) {
        this.$message.error("上传头像图片大小不能超过 2MB!");
      } else if (!isJPG && !isPNG && !isJPEG) {
        this.$message.error("上传头像图片只能是 JPG/PNG 格式!");
      }
      return isJPEG || isJPG || (isPNG && isLt2M);
    },
    handleAvatarSuccess(response, file) {
      console.log(response);
      this.settingForm = {
        ...this.settingForm,
        headImg: response.url,
      };
    },
    // 校验函数
    truncateText(input, maxChineseChars, maxEnglishChars, totalMaxChars) {
      // 计算截取的最大长度
      var maxLength = 0;
      if (input.match(/^[\u4e00-\u9fa5]+$/)) {
        maxLength = Math.min(maxChineseChars * 2, totalMaxChars);
      } else {
        maxLength = Math.min(maxEnglishChars, totalMaxChars);
      }

      // 循环遍历字符串，计算实际长度
      var length = 0;
      var truncatedText = "";
      for (var i = 0; i < input.length; i++) {
        var charCode = input.charCodeAt(i);
        // 判断字符是否为中英文或数字
        if (
          (charCode >= 48 && charCode <= 57) || // 数字 0-9
          (charCode >= 65 && charCode <= 90) || // 大写字母 A-Z
          (charCode >= 97 && charCode <= 122) || // 小写字母 a-z
          (charCode >= 19968 && charCode <= 40869) // 中文字符范围
        ) {
          if (charCode >= 19968) {
            // 中文字符和全角字符占两个字节
            if (
              length + 2 > maxLength ||
              truncatedText.length >= totalMaxChars
            ) {
              break;
            }
            truncatedText += input[i];
            length += 2;
          } else {
            // 英文、数字和其他字符占一个字节
            if (
              length + 1 > maxLength ||
              truncatedText.length >= totalMaxChars
            ) {
              break;
            }
            truncatedText += input[i];
            length += 1;
          }
        }
      }
      return truncatedText;
    },
    // 转换 数组中含 图片类型 (为什么不直接在新增时 转换, 因为每次拿回来的数据 如果有图片都需要去掉value)
    async processArray(button) {
      for (let i = 0; i < button.length; i++) {
        if (button[i].sub_button && Array.isArray(button[i].sub_button.list)) {
          // 如果当前元素有 subarr 属性且是一个数组，则递归调用 processArray 处理子数组
          // 递归会导致 序列化同步先执行,所以改成 for循环
          // this.processArray(button[i].sub_button.list);
          let arr = button[i].sub_button.list;
          for (let j = 0; j < arr.length; j++) {
            if (arr[j].type == "media_id") {
              if (arr[j].headImg) {
                const res = await this.updateImg(arr[j].headImg);
                arr[j].media_id = res && JSON.parse(res).media_id;
                // 去掉 传送图片值的中间变量
                arr[j].value = arr[j]["headImg"];
                delete arr[j]["headImg"];
              } else {
                delete arr[j].value;
              }
            }
          }
        }
        if (button[i].type == "media_id") {
          if (button[i].headImg) {
            const res = await this.updateImg(button[i].headImg);
            button[i].media_id = res && JSON.parse(res).media_id;
            // 去掉 传送图片值的中间变量
            button[i].value = button[i]["headImg"];
            delete button[i]["headImg"];
          } else {
            delete button[i].value;
          }
        }
      }
      return button;
    },
    // 上传微信图片
    async updateImg(url) {
      const res = await uploadWxImgDto(url);
      return res.data;
    },
  },
};
</script>
<style lang="scss" scoped>
// 隐藏
.hidden {
  opacity: 0;
  pointer-events: none;
}
.btn {
  padding: 0;
}
.newBtn2 {
  color: #409eff;
}
.newBtn {
  color: #999999 !important;
}
.app-container {
  padding-top: 38px;
  box-sizing: border-box;
  display: flex;
  justify-content: space-evenly;
  .left_container {
    width: 23rem;
    height: 40rem;
    background-color: #ededed;
    .mobile {
      position: relative;
      width: 100%;
      box-sizing: border-box;
      background: #ededed;
      border: 1px solid #eaeaf4;
      height: 100%;
      img {
        vertical-align: middle;
        border-style: none;
        width: 100%;
      }
      .mobile_title {
        display: inline-block;
        position: absolute;
        font-size: 1rem;
        font-weight: 500;
        left: 50%;
        -webkit-transform: translateX(-50%);
        transform: translateX(-50%);
        top: 3rem;
      }
      .btn {
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 45px;
        background: #f7f7f7;
        border-top: 1px solid #d8d8d8;
        align-items: center;
        display: flex;
        .icon_btn {
          width: 45px;
          display: flex;
          justify-content: center;
          img {
            width: 25px;
          }
        }
        .main_btn {
          flex: 1;
          text-overflow: ellipsis;
          overflow: hidden;
          white-space: nowrap;
          border-left: 1px solid #d2d2dc;
          background: #f7f7f7;
          // color: #1e1e29;
          ::v-deep .el-button {
            padding: 12px 0;
            font-size: 12px;
          }
          .main_btn1 {
            background: #f7f7f7;
            width: 100%;
            border: none;
          }
        }
      }
      .subMenu {
        position: absolute;
        left: 0;
        bottom: 44px;
        z-index: 1;
        width: 100%;
        display: flex;
        .subBtn {
          flex: 1;
          display: flex;
          flex-direction: row;
          height: 225px;
          align-items: flex-end;
          ::v-deep .el-button {
            padding: 12px 0;
            font-size: 12px;
          }
          .sub_btn {
            display: flex;
            height: 45px;
            flex-direction: column-reverse;
            flex: 1;
            .add_btn {
              height: 38px;
              border: 1px solid #d2d2dc;
              background: #f7f7f7;
              width: 100%;
              border-bottom: none;
              box-sizing: border-box;
              &:last-child {
                border: 1px solid #d2d2dc;
              }
            }
          }
        }
      }
    }
  }
  .right_container {
    display: flex;
    flex-direction: column;
    padding-left: 4rem;
    box-sizing: border-box;
    flex: 1;
    position: relative;
    .setting {
      display: flex;
      flex-direction: column;
      padding-right: 1rem;
      box-sizing: border-box;
      .title {
        font-size: 22px;
        font-weight: 700;
        margin-bottom: 10px;
      }
      .content {
        .form_content {
          width: 90%;
          height: 20rem;
          background-color: #ededed;
          margin: 1rem 0 0 4rem;
          box-sizing: border-box;
          .xcx {
            padding: 20px 0 0 10px;
            box-sizing: border-box;
            img {
              width: 2rem;
              height: 2rem;
              margin: 0 1rem;
              box-sizing: border-box;
              border: 1px solid #000;
              border-radius: 50%;
            }
          }
          .pageUrl {
            display: flex;
            padding-top: 20px;
            padding-left: 10px;
            box-sizing: border-box;
          }
        }
      }
    }
    .alt {
      text-align: center;
      margin: auto;
    }
    .footer {
      position: absolute;
      bottom: 0;
      right: 50%;
      transform: translateX(25%);
    }
  }
}
::v-deep .el-textarea__inner {
  margin-left: 2rem;
  width: 60%;
  height: 8rem;
}
::v-deep .el-textarea .el-input__count {
  background-color: transparent;
  color: #000;
  position: absolute;
  right: 37%;
  bottom: -2rem;
}
.data-class {
  margin-left: 5rem;
}

// 图片上传
::v-deep .avatar-uploader {
}
::v-deep .el-upload__tip {
  margin-top: -1rem;
}
.avatar {
  width: 6rem;
  height: 6rem;
  display: block;
}
::v-deep .el-form-item {
  margin-bottom: 0;
}
::v-deep .avatar-uploader {
  margin-left: 2rem;
}
::v-deep .avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 6rem;
  height: 6rem;
  line-height: 6rem;
  text-align: center;
}
::v-deep .el-upload:hover {
  border-color: #409eff;
}
::v-deep .el-upload {
  border: 2px dashed #8c939d;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  background-color: #fff;
}
::v-deep .el-form-item__error {
  left: 34%;
  top: 31%
}
</style>
